<template>
  <el-form
    ref="form"
    label-width="120px"
    :validate-on-rule-change="false"
  >
    <template v-for="(edit, index) in editList">
      <el-form-item
        v-if="!edit.hideItem"
        :key="index"
        :label="edit.label"
        :prop="edit.key"
        :class="{'have': edit.have}"
      >
        <el-input
          v-if="edit.type === 'input'"
          v-model="edit.value"
          :disabled="edit.disabled"
          :placeholder="edit.placeholder || '请输入'"
        />
        <el-input
          v-else-if="edit.type === 'textarea'"
          :show-word-limit="edit.showWordLimit"
          :maxlength="edit.maxlength"
          v-model="edit.value"
          type="textarea"
          :disabled="edit.disabled"
          :placeholder="edit.placeholder"
        />
        <el-radio-group
          v-else-if="edit.type === 'radio'"
          v-model="edit.value"
          @change="value => change(value, edit)"
        >
          <div class="radio-group">
            <template v-for="item in edit.data">
              <el-radio v-model="item.value" :key="item.value" :label="item.value">{{ item.title }}</el-radio>
              <el-date-picker
                v-if="item.date && edit.value == item.value" 
                :key="item.value+'date'"
                v-model="item.date.value"
                value-format="yyyy-MM-dd HH:mm:ss"
                type="datetime"
                placeholder="选择日期时间">
              </el-date-picker>
            </template>
          </div>
        </el-radio-group>
        <el-select
          v-else-if="edit.type === 'select'"
          v-model="edit.value"
          filterable
          :disabled="edit.disabled"
          :placeholder="edit.placeholder"
          @change="value => change(value, edit)"
        >
          <el-option
            v-for="item in edit.options"
            :key="item.value"
            :label="item.title"
            :value="item.value"
          />
        </el-select>
        <div v-else-if="edit.type === 'select-group'" class="select-group">
          <template v-for="item in edit.data">
            <span class="selects-tag" :key="item.key+'span'" v-if="item.tag">{{item.tag}}</span>
            <el-select :key="item.key" v-model="item.value" placeholder="请选择">
              <el-option
                v-for="item2 in item.data"
                :key="item2.key"
                :label="item2.key"
                :value="item2.value">
              </el-option>
            </el-select>
          </template>
        </div>
        <el-upload
          v-else-if="edit.type === 'upload'"
          :class="['upload-box',upStatu == 1 ? '' : 'br1']"
          :action="`${apiUrl}/oss/file-anon`"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
          :on-progress="onProgress"
          :on-error="onError"
        >
          <el-progress v-if="upStatu == 1" type="circle" :width="100" :percentage="upProgress" />
          <el-image v-else-if="form[edit.key]" style=" width: 98px;height: 98px;" :src="form[edit.key] || imageUrl" fit="fit" />
          <i v-else class="el-icon-plus avatar-uploader-icon" />
        </el-upload>
        <slot v-else-if="edit.type === 'slot'" :edit="edit" :name="edit.name" />
        <div v-if="edit.tip" class="tip">{{edit.tip}}</div>
        <div v-if="edit.event" @click="editEvent(edit.event.fn)" class="event">{{edit.event.title}}</div>
      </el-form-item>
    </template>
    <slot />
  </el-form>
</template>

<script>
export default {
  props: {
    editList: {
      type: Array,
      default() {
        return {}
      }
    },
    params: {
      type: Object,
      default() {
        return null
      }
    }
  },
  data() {
    return {
      imageUrl: '',
      apiUrl: process.env.VUE_APP_BASE_API,
      upStatu: 0, // 1上传中
      upProgress: 0,
      progressNum: 10,
      realityPro: 0
    }
  },
  computed: {
    _editList() {
      return this.editList;
    },
    _editParams() {
      return this.params;
    }
  },
  methods: {
    editEvent(fn) {
      this.$emit(fn, '')
    },
    
    change(value, edit) {
      if (edit.change) edit.change(value);
    },
    _error(title) {
      this.$message.error(title);
      throw title;
    },
    ruleFrom() {
      const from = {};
      this._editList.forEach(item => {
        let _params = null;
        if (!item.notParams && !item.hideItem) {
          if (item.setParams) {
            _params = item.setParams();
          } else {
            if (item.value || typeof item.value === 'number' || typeof item.value === 'boolean') _params = {[item.key]: item.value}
          }
        }
        if (item.have && !item.notParams && !_params && !item.hideItem) this._error(item.label + '为必要项') 
        Object.assign(from, _params);
      })
      if (this._editParams) Object.assign(from, this._editParams);
      return from;
    },
    onProgress(event) {
      this.upStatu = 1
      this.realityPro = event.percent
    },
    onError() {
      setTimeout(() => {
        this.$message.error('图片上传失败')
        this.upStatu = 0
      }, 500)
    },
    removeImageUrl() {
      this.imageUrl = ''
    },
    handleAvatarSuccess(res, file) {
      // this.upStatu = 0
      this.$message.success('图片上传成功')
      this.imageUrl = URL.createObjectURL(file.raw)
      this.$emit('uploade', res.data.netUrl)
    },
    getUpProgress() {
      setTimeout(() => {
        this.upProgress += (100 / this.progressNum)
        if (this.upProgress > this.realityPro) this.upProgress = Math.floor(this.realityPro)
        if (this.upProgress < 100) {
          this.getUpProgress()
        } else {
          this.upStatu = 0
        }
      }, 100)
    },
    beforeAvatarUpload(file) {
      this.upProgress = 0
      this.upStatu = 0
      this.realityPro = 0
      this.getUpProgress()
      return true
    }
  }
}
</script>

<style lang="scss" scoped>
  ::v-deep .el-textarea__inner{
    height: 100px;
  }
  .el-select{
    width: 100%;
  }
  .w1{
    width: 49%;
  }
  .m1{
    margin-left: 2%;
  }
  .br1{
    border: 1px solid #DCDFE6;
  }
  .upload-box{
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
    border-radius: 6px;
  }
  ::v-deep .el-upload--text{
    width: 100%;
    height: 100%;
  }
  .upload-box:hover{
    border-color: #409EFF;
  }
  .avatar-uploader-icon{
    font-size: 26px;
    color: #8c939d;
  }
  .have::v-deep .el-form-item__label:before {
    content: "*";
    color: #ff4949;
    margin-right: 4px;
  }
  .select-group, .radio-group{
    display: flex;
  }
  .radio-group{
    align-items: center;
    .el-input{
      margin-right: 20px;
    }
  }
  .selects-tag{
    margin: 0 10px;
  }
  .tip{
    position: absolute;
    left: 0;
    bottom: -23px;
    line-height: 20px;
    font-weight: 400;
    font-size:12px;
    color:#999999;
    z-index: 6;
  }
  .event{
    position: absolute;
    left: 0;
    bottom: -25px;
    line-height: 20px;
    font-weight: 400;
    font-size:12px;
    color:#2c57df;
    z-index: 6;
    cursor: pointer;
  }
</style>
